package com.job51.hro.exlog.box;

import org.apache.logging.log4j.util.Strings;
import org.springframework.http.MediaType;
import org.springframework.web.filter.GenericFilterBean;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.IOException;
import java.io.InputStream;
import java.io.PushbackInputStream;

/**
 * 〈一句话功能简述〉<br>
 * 〈〉
 *
 * @author pengfei.ma
 * @create 2023/3/7
 * @since 1.0.0
 */
public class WebPostJsonFilter extends GenericFilterBean {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        if (Strings.isNotBlank(request.getContentType()) && request.getContentType().contains(MediaType.APPLICATION_JSON_VALUE)) {
            request = new PushbackInputStreamHttpServletRequestWrapper(request);
        }
        filterChain.doFilter(request, servletResponse);
    }

    public static class PushbackInputStreamHttpServletRequestWrapper extends HttpServletRequestWrapper {

        private ServletInputStream inputStream;

        public PushbackInputStreamHttpServletRequestWrapper(HttpServletRequest request) {
            super(request);
        }

        @Override
        public ServletInputStream getInputStream() throws IOException {
            if (this.inputStream == null) {
                this.inputStream = new PushbackServletInputStream(getRequest().getInputStream(), getRequest().getContentLength());
            }
            return this.inputStream;
        }
    }

    public static class PushbackServletInputStream extends ServletInputStream {

        private final PushbackInputStream pushbackInputStream;

        private PushbackServletInputStream(InputStream in, int size) {
            pushbackInputStream = new PushbackInputStream(in, size);
        }

        @Override
        public boolean isFinished() {
            return false;
        }

        @Override
        public boolean isReady() {
            return false;
        }

        @Override
        public void setReadListener(ReadListener readListener) {

        }

        @Override
        public int read() throws IOException {
            return pushbackInputStream.read();
        }

        public void unread(byte[] b) throws IOException {
            pushbackInputStream.unread(b);
        }
    }
}
